// 引入 登录，退出登录，获取用户信息的接口函数
import { login, logout, getInfo } from '@/api/user'
// 引入  获取token，，设置token，，删除token函数
import { getToken, setToken, removeToken } from '@/utils/auth'
// 引入  路由模块当中重置路由的方法
import { resetRouter, asyncRoutes, constantRoutes, anyRoutes } from '@/router'
import router from '@/router'

const getDefaultState = () => {
    return {
        // 获取token
        token: getToken(),
        // 存储用户名
        name: '',
        // 存储用户头像
        avatar: '',
        // 菜单标记【根据不同的角色，返回不同的标记信息，数组里的元素是字符串】
        routes: [],
        // 角色的信息
        roles: [],
        // 按钮权限的信息
        buttons: [],
        // 对比之后，项目中已有的异步路由，与服务器返回的标记的信息进行对比，、最终显示的路由。
        resultAsyncRoutes: [],
        // 需要展示的所有路由
        resultAllRoutes: []
    }
}

// state中的值，就是你上面箭头函数===>返回的那个对象的数据
const state = getDefaultState()

// 修改state的唯一手段
const mutations = {
    // 重置state
    RESET_STATE: (state) => {
        Object.assign(state, getDefaultState())
    },
    // 存储token
    SET_TOKEN: (state, token) => {
        state.token = token
    },
    // 存储用户信息的
    SET_USERINFO: (state, userInfo) => {
        // 用户名、
        state.name = userInfo.name
            // 用户头像
        state.avatar = userInfo.avatar
            // 菜单权限标记
        state.routes = userInfo.routes
            // 按钮权限标记
        state.buttons = userInfo.buttons
            // 角色信息
        state.roles = userInfo.roles
    },
    // 最终计算出的异步路由
    SET_RESULTASYNCROUTES: (state, asyncRoutes) => {
        // vuex保存的是当前用户的异步路由，注意：一个用户需要展示：常量，异步，任意路由
        state.resultAsyncRoutes = asyncRoutes
            // 计算出当前用户需要展示的所有路由
        state.resultAllRoutes = constantRoutes.concat(state.resultAsyncRoutes, anyRoutes)
            // 给路由器添加新的路由
        router.addRoutes(state.resultAllRoutes)
    }
}

// 定义一个函数， 进行对比， 对比出当前用户到底需要展示哪些异步路由？
const computedAsyncRoutes = (asyncRoutes, routes) => {
    // 过滤出当前用户【超级管理员|普通员工】需要展示的异步路由。！
    return asyncRoutes.filter(item => {
        // console.log(item);
        if (routes.indexOf(item.name) !== -1) {
            // 如果有2级路由呢！？
            // 递归
            if (item.children && item.children.length) {
                item.children = computedAsyncRoutes(item.children, routes)
            }
            return true
        }
    })
}
const actions = {
    // 这里处理登录业务。
    async login({ commit }, userInfo) {
        // 解构出用户名与密码
        const { username, password } = userInfo
        let result = await login({ username: username.trim(), password: password })
            // 注意：当前登录请求现在使用mock数据，mock数据code是20000
        if (result.code == 20000) {
            // vuex存储token
            commit('SET_TOKEN', result.data.token)
                // 本地持久化存储token
            setToken(result.data.token)
        } else {
            return Promise.reject(new Error('faile'))
        }

        // return new Promise((resolve, reject) => {
        //     login({ username: username.trim(), password: password }).then(response => {
        //         const { data } = response
        //         commit('SET_TOKEN', data.token)
        //         setToken(data.token)
        //         resolve()
        //     }).catch(error => {
        //         reject(error)
        //     })
        // })
    },

    // 获取用户信息
    getInfo({ commit, state }) {
        return new Promise((resolve, reject) => {
            getInfo(state.token).then(response => {
                console.log(response);
                // 获取用户信息，返回包含用户名name，头像avatar，
                // routes[返回的标志。不同的用户应该展示哪些菜单]
                // roles【用户角色信息】、buttons【按钮信息：按钮权限用的标记】
                const { data } = response

                //vuex存储用户的全部信息
                commit('SET_USERINFO', data)
                    // asyncRoutes 和 data.routes对比
                commit('SET_RESULTASYNCROUTES', computedAsyncRoutes(asyncRoutes, data.routes))

                resolve(data)
            }).catch(error => {
                reject(error)
            })
        })
    },

    // user logout
    logout({ commit, state }) {
        return new Promise((resolve, reject) => {
            logout(state.token).then(() => {
                removeToken() // must remove  token  first
                resetRouter()
                commit('RESET_STATE')
                resolve()
            }).catch(error => {
                reject(error)
            })
        })
    },

    // remove token
    resetToken({ commit }) {
        return new Promise(resolve => {
            removeToken() // must remove  token  first
            commit('RESET_STATE')
            resolve()
        })
    }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}